SnowflakeのStreamlitアプリからモデルレジストリのモデルを利用する

SnowflakeのStreamlitアプリからモデルレジストリのモデルを利用する

2024年12月時点で、Streamlit in Snowflakeのアプリ実行時に、Snowpark MLのモデルレジストリに登録したモデルを使って推論を実行する方法についてまとめました。
Clock Icon2024.12.08

データ事業本部 インテグレーション部 機械学習チームの鈴木です。
この記事は、Snowflake Advent Calendar 2024シリーズ2の9日目の記事です。

SnowflakeのStreamlit機能はとても便利です。Snowflakeに格納したデータを分析するアプリを非常に簡単に作成することができます。

また、Snowflakeでは、機械学習の機能にも力が入れられています。Snowlfake MLとしてSQLから利用できるML Functionsのような組み込みのAI/ML機能があるほか、Snowpark MLを使えばPythonを使ってモデルを開発し、ネイティブなモデルレジストリに格納してPythonおよびSQLより利用できます。

今年の夏時点での機械学習機能については、以下の発表でまとめました。

https://dev.classmethod.jp/articles/devio2024-snowflake-ml-overview-20240723/

今回はStreamlitアプリから直接モデルレジストリに格納したSnowpark MLを実行し、結果を取得する方法を試してみたのでまとめます。

StreamlitアプリからのSnowpark MLの実行

この記事では、Streamlitアプリからモデルレジストリに登録したSnowpark ML Modelingのモデルを使って推論する方法を範囲に記載します。

私が考える中では、以下の3つの方法があります。

  1. SnowparkでSQLを実行する
    • 推論を実行するSQL文を実行する
    • 推論を実行するVIEWを作っておき実行する
  2. Snowpark MLを使う

Streamlitアプリはアプリ実行時にプログラムの上から順番に処理が実行されますが、推論のような多少の実行時間がかかる処理を入れるとアプリの表示が遅くなってしまいます。
バッチ処理で推論した後のデータをテーブルに格納しておき、アプリではそのデータを取得して表示する方がよいですが、社内で利用する分析用アプリのような場合は今回紹介する方法でもよい場合も多いですね。

全体像としては以下のようになります。

紹介する仕組み

実装の紹介

SnowparkでSQLを実行する案

SQLを使ってモデルレジストリのモデルを利用する案を2つ考えました。

以下のようにStreamlitで推論結果を取得できました。

推論結果

推論を実行するSQL文を実行する案

sqlメソッドを使うことで、Streamlitアプリ上で実装したSQL文を実行することができます。

例えば以下のように最新のモデルを使った推論を実行するSQL文を作成し、実行します。

def run_ml(session):
    sql_str = """
    WITH MV AS MODEL "IRIS_XGBOOST_REGRESSOR" VERSION "LAST"
        SELECT
            MV!PREDICT(SEPAL_WIDTH, PETAL_LENGTH, SPECIES, SEPAL_LENGTH):PREDICTED_PETAL_WIDTH::FLOAT AS PREDICTED_PETAL_WIDTH
        FROM (
            SELECT 
                *
            FROM IRIS
        )
    ;
    """
    df = session.sql(sql_str)
    return df.to_pandas().head()

推論結果はPandasデータフレームに変換し、st.dataframeメソッドなどで表示できます。

推論を実行するVIEWを作っておき実行する案

実行される処理としてはほぼ同じですが、先に推論用のビューを作成しておき、tableメソッドを使って推論実行をすることもできます。

例えば以下のように最新のモデルを使った推論を実行するビューを作成します。

CREATE OR REPLACE VIEW ML_VIEW
AS
WITH MV AS MODEL "IRIS_XGBOOST_REGRESSOR" VERSION "LAST"
SELECT
  MV!PREDICT(SEPAL_WIDTH, PETAL_LENGTH, SPECIES, SEPAL_LENGTH):PREDICTED_PETAL_WIDTH::FLOAT AS PREDICTED_PETAL_WIDTH
FROM (
    select 
      *
     FROM IRIS
);

Streamlitアプリ内で以下の関数を作成し、ビューを実行して推論結果を取得します。

def run_ml_view(session):
    ml_view = 'ML_VIEW'
    df = session.table(ml_view)
    return df.to_pandas().head()

Snowpark MLを使う案

StreamlitはPythonライブラリのため、Snowpark MLを使ってモデルバージョンを取得し、推論を実行する案が考えられます。
例えば以下のようなPythonスクリプトを実行するイメージです。

## 以下のガイドを参考
## https://docs.snowflake.com/en/developer-guide/snowflake-ml/model-registry/overview

from snowflake.ml.registry import Registry

reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
m = reg.get_model("MyModel")
mv = m.version("LAST")
remote_prediction = mv.run(test_features, function_name="predict")

なお、現状はStreamlit in SnowflakeのランタイムのPythonバージョンは3.8のため、snowflake-ml-python
ライブラリは非対応です。Snowpark ML案は今後バージョンが上がるのを待ちましょう。
snowflake-ml-pythonの対応Pythonバージョンは以下をご確認ください。

https://github.com/snowflakedb/snowflake-ml-python

補足

今回はモデルレジストリにIrisデータの花弁の幅を推定する訓練済みのXGBoostモデルを登録しておきました。

Irisデータは以下のサイトからダウンロードしました。

https://archive.ics.uci.edu/ml/datasets/iris

モデルレジストリに適当なバージョン名で登録し、LASTエイリアスで最新のものを使用しました。エイリアスについては以下の記事に記載しております。

https://dev.classmethod.jp/articles/use-latest-version-model-snowpark-ml-model-registry/

最後に

SnowflakeのStreamlitアプリから、直接モデルレジストリに格納したSnowpark MLを実行し結果を取得する方法をご紹介しました。参考になりましたら幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.